;(function(factory) {
	if(typeof define === 'function' && define.amd) {
		define(['frame/XFrame_Graph', 'frame/BaseShape', 'frame/CommonShape'], factory);
	}else {
		factory(XFrame_Graph, BaseShape, CommonShape, window);
	}
}(function(XFrame_Graph, BaseShape, CommonShape, global) {
	'use strict';
	var TNodes = {}, NodeShape, TopologyShape, createdNodes = {}, BaseNode , tLines = null, _nodeDragHandler;
	
	_nodeDragHandler = function(e){
		if(tLines){
			tLines.updateCommands();
		}
	};
	
	NodeShape = BaseShape.extend({
		init : function(conf){
			conf = conf || {};
			this.dragable = true;
			this.radius = conf.radius || 5;
			this.borderColor = '#cccccc';
			
			this.bindEvent('dragging', _nodeDragHandler);
		},
		drawDefine : function(){
			var dd = new XFrame_Graph.drawDefiner();
			dd.style('Stroke', this.borderColor);
			dd.style('Fill', 'white');
			dd.style('Shadow', '#dfe2e7', 6);
			dd.draw('FilletRect', this.posX, this.posY, this.width, this.height, this.radius);
			
			dd.changeEditType('hover');
			dd.style('Stroke', this.borderColor);
			dd.style('Fill', 'white');
			dd.style('Shadow', '#8fb7e2', 6);
			dd.draw('FilletRect', this.posX, this.posY, this.width, this.height, this.radius);
			
			dd.changeEditType('active');
			dd.style('Stroke', this.borderColor);
			dd.style('Fill', '#e7f3ff');
			dd.style('Shadow', '#8fb7e2', 6);
			dd.draw('FilletRect', this.posX, this.posY, this.width, this.height, this.radius);
			return dd.getCommands();
		}
	});
	
	TopologyShape = BaseShape.extend({
		init : function(){
			
			this.disableEvents = true;
			this.unbindEvent();
			this.zindex = -999;
		},
		drawDefine : function(){
			var tmpNodesPoint = {}, tmpNode, tmpSubNode, mainuuid = null, subuuid = null
				, dd = new XFrame_Graph.drawDefiner();
			dd.style('Stroke', '#cccccc');
			for(mainuuid in createdNodes){
				tmpNode = createdNodes[mainuuid];
				!tmpNodesPoint[mainuuid] && (tmpNodesPoint[mainuuid] = tmpNode.getNodePoint());
				for(subuuid in tmpNode.subNodes){
					tmpSubNode = tmpNode.subNodes[subuuid];
					!tmpNodesPoint[subuuid] && (tmpNodesPoint[subuuid] = tmpSubNode.getNodePoint());
					dd.draw('HalfFilletRect', tmpNodesPoint[mainuuid][0], tmpNodesPoint[mainuuid][1], tmpNodesPoint[subuuid][0], tmpNodesPoint[subuuid][1], 5, true);
				}
			}
			return dd.getCommands();
		}
	});
	
	BaseNode = XFrame_Graph._createClass({
		init : function(){
			this.subNodes = {};
			this.mainShape = null;
			this.uuid = XFrame_Graph._genId();
			createdNodes[this.uuid] = this;
		},
		getNodePoint : function(){
			var x = 0,y = 0;
			if(this.mainShape){
				x = this.mainShape.posX + this.mainShape.width / 2;
				y = this.mainShape.posY + this.mainShape.height / 2;
			}
			
			return [x, y];
		},
		pointTo : function(subNode){
			this.subNodes[subNode.uuid] = subNode;
			return this;
		}
	});
	
	TNodes.VmNode = BaseNode.extend({
		init : function(conf){
			conf = conf || {};
			this.mainShape = new NodeShape({
				width : 110,
				height : 120,
				posX : conf.posX || 50,
				posY : conf.posY || 50
			});
			this.mainShape.regist();
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot_vm.png',
				posX : 24,
				posY : 15,
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.name = new CommonShape.TextShape({
				text : conf.name || 'ThisVm',
				align : 'center',
				font : '14px \'Microsoft YaHei\',Arail',
				posX : 55,
				posY : 82,
				width : 80,
				parentShape : this.mainShape
			});
			this.name.regist();
		}
	});
	
	TNodes.EthNode = BaseNode.extend({
		init : function(conf){
			conf = conf || {};
			this.mainShape = new NodeShape({
				width : 160,
				height : 90,
				posX : conf.posX || 200,
				posY : conf.posY || 200
			});
			this.mainShape.regist();
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot.png',
				posX : 15,
				posY : 15,
				offsetInfo : [0, 0, 19, 16],
				scaleSize : [19, 16],
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.ethName = new CommonShape.TextShape({
				text : conf.eth,
				font : 'bold 12px \'Microsoft YaHei\',Arail',
				posX : 45,
				posY : 15,
				width : 98,
				parentShape : this.mainShape
			});
			this.ethName.regist();
			
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot.png',
				posX : 15,
				posY : 36,
				offsetInfo : [0, 16, 19, 16],
				scaleSize : [19, 16],
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.ip = new CommonShape.TextShape({
				text : conf.ip,
				font : '12px \'Microsoft YaHei\',Arail',
				posX : 45,
				posY : 36,
				width : 98,
				parentShape : this.mainShape
			});
			this.ip.regist();
			
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot.png',
				posX : 15,
				posY : 57,
				offsetInfo : [0, 32, 19, 16],
				scaleSize : [19, 16],
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.mac = new CommonShape.TextShape({
				text : conf.mac,
				font : '12px \'Microsoft YaHei\',Arail',
				posX : 45,
				posY : 57,
				width : 98,
				parentShape : this.mainShape
			});
			this.mac.regist();
		}
	});
	
	TNodes.EthInfoNode = BaseNode.extend({
		init : function(conf){
			conf = conf || {};
			this.mainShape = new NodeShape({
				width : 132,
				height : 69,
				posX : conf.posX || 350,
				posY : conf.posY || 350
			});
			this.mainShape.regist();
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot.png',
				posX : 15,
				posY : 15,
				offsetInfo : [0, 48, 19, 16],
				scaleSize : [19, 16],
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.vlan = new CommonShape.TextShape({
				text : conf.vlan,
				font : '12px \'Microsoft YaHei\',Arail',
				posX : 45,
				posY : 15,
				width : 70,
				parentShape : this.mainShape
			});
			this.vlan.regist();
			
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot.png',
				posX : 15,
				posY : 36,
				offsetInfo : [0, 64, 19, 16],
				scaleSize : [19, 16],
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.slist = new CommonShape.TextShape({
				text : conf.slist,
				font : '12px \'Microsoft YaHei\',Arail',
				posX : 45,
				posY : 36,
				width : 70,
				parentShape : this.mainShape
			});
			this.slist.regist();
			
		}
	});
	
	TNodes.StorageTotalNode = BaseNode.extend({
		init : function(conf){
			conf = conf || {};
			this.mainShape = new NodeShape({
				width : 182,
				height : 126,
				posX : conf.posX || 50,
				posY : conf.posY || 50
			});
			this.mainShape.regist();
			this.iconShape = new CommonShape.ImageShape({
				url : (conf.urlBase || 'http://20.1.193.5:8080') + '/img/gplot_StoragePools.png',
				posX : 72,
				posY : 15,
				parentShape : this.mainShape
			});
			this.iconShape.regist();
			
			this.name = new CommonShape.TextShape({
				text : conf.name || 'StoragePool',
				align : 'center',
				font : '14px \'Microsoft YaHei\',Arail',
				posX : 91,
				posY : 68,
				width : 180,
				parentShape : this.mainShape
			});
			this.name.regist();
			
			this.process = new CommonShape.processShape({
				pv: conf.pv || 0,
				showText : true,
				text : conf.pvtext || '0 / 0GB',
				width : 132,
				height : 10,
				posX : 25,
				posY : 99,
				parentShape : this.mainShape
			});
			this.process.regist();
			
		}
	});
	
	TNodes.initTopology = function(sel){
		XFrame_Graph.initCanvas(sel);
		createdNodes = {};
		tLines = new TopologyShape();
	};
	
	TNodes.showTopology = function(){
		if(!tLines){
			return;
		}
		tLines.regist();
		XFrame_Graph.show();
	};
	
	TNodes.setScale = XFrame_Graph.setGraphScale;
	
	global && (global.Topology = TNodes);
	return TNodes;
}));